from django.test import TestCase
from rest_framework.test import APITestCase
from rest_framework import status
from django.urls import reverse
from apps.keys_management.models import RootKey, KeyAuditLog
from apps.generate_secret.models import AppSecret
from apps.generate_secret.tools import generate_signature
import json
import time
from datetime import datetime


class RootKeyModelTest(TestCase):
    """根密钥模型测试"""

    def test_generate_key_id(self):
        """测试生成密钥ID"""
        key_id = RootKey.generate_key_id()
        self.assertIsInstance(key_id, str)
        self.assertEqual(len(key_id), 16)

    def test_generate_root_key(self):
        """测试生成根密钥"""
        root_key = RootKey.generate_root_key(128)
        self.assertIsInstance(root_key, str)
        self.assertEqual(len(root_key), 32)  # 128位 = 16字节 = 32个十六进制字符

    def test_generate_version(self):
        """测试生成版本号"""
        version = RootKey.generate_version()
        self.assertIsInstance(version, str)
        self.assertTrue(version.startswith('v1.0.'))

    def test_create_root_key(self):
        """测试创建根密钥记录"""
        root_key = RootKey.objects.create(
            key_id=RootKey.generate_key_id(),
            key=RootKey.generate_root_key(128),
            key_type='SM4',
            key_length=128,
            description='测试密钥',
            version=RootKey.generate_version(),
            status='active'
        )
        self.assertEqual(root_key.key_type, 'SM4')
        self.assertEqual(root_key.key_length, 128)
        self.assertEqual(root_key.status, 'active')


class RootKeyAPITest(APITestCase):
    """根密钥API测试"""

    def setUp(self):
        """测试前准备"""
        # 创建测试应用秘钥
        self.test_app = AppSecret.objects.create(
            app_id="test_app_12345",
            app_secret="test_secret_67890",
            app_name="测试应用",
            remark="测试备注"
        )
        # 生成测试签名参数
        self.sender_nonce = "sender_nonce_123"
        self.recip_nonce = "recip_nonce_456"
        self.message_time = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
        
        # 生成签名token
        signature_params = {
            "app_id": self.test_app.app_id,
            "senderNonce": self.sender_nonce,
            "recipNonce": self.recip_nonce,
            "messageTime": self.message_time
        }
        self.token = generate_signature(signature_params, self.test_app.app_secret)

    def _get_headers(self):
        """获取测试用的头信息"""
        return {
            'HTTP_APP_ID': self.test_app.app_id,
            'HTTP_TOKEN': self.token
        }

    def _get_params(self):
        """获取测试用的参数"""
        return {
            'senderNonce': self.sender_nonce,
            'recipNonce': self.recip_nonce,
            'messageTime': self.message_time
        }

    def test_generate_root_key_success(self):
        """测试成功生成根密钥"""
        url = '/api/keys_management/keys/generateRoot'
        data = {
            'key_type': 'SM4',
            'key_length': 128,
            'description': '测试密钥'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.post(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 0)  # DetailResponse返回code=0
        self.assertIn('key_id', result['data'])
        self.assertIn('key', result['data'])
        self.assertIn('description', result['data'])
        self.assertIn('created_at', result['data'])
        self.assertIn('version', result['data'])
        self.assertIn('status', result['data'])
        self.assertEqual(result['data']['status'], 'active')

    def test_generate_root_key_missing_key_type(self):
        """测试缺少key_type参数"""
        url = '/api/keys_management/keys/generateRoot'
        data = {
            'key_length': 128,
            'description': '测试密钥'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.post(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('key_type参数不能为空', result['data'])

    def test_generate_root_key_invalid_key_type(self):
        """测试无效的key_type参数"""
        url = '/api/keys_management/keys/generateRoot'
        data = {
            'key_type': 'AES',
            'key_length': 128,
            'description': '测试密钥'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.post(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('key_type参数必须是SM1或SM4', result['data'])

    def test_generate_root_key_missing_key_length(self):
        """测试缺少key_length参数"""
        url = '/api/keys_management/keys/generateRoot'
        data = {
            'key_type': 'SM4',
            'description': '测试密钥'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.post(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('key_length参数不能为空', result['data'])

    def test_generate_root_key_invalid_key_length(self):
        """测试无效的key_length参数"""
        url = '/api/keys_management/keys/generateRoot'
        data = {
            'key_type': 'SM4',
            'key_length': 256,
            'description': '测试密钥'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.post(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('key_length参数必须是128', result['data'])

    def test_get_root_key_list(self):
        """测试获取根密钥列表"""
        # 先创建一个测试密钥
        root_key = RootKey.objects.create(
            key_id=RootKey.generate_key_id(),
            key=RootKey.generate_root_key(128),
            key_type='SM4',
            key_length=128,
            description='测试密钥',
            version=RootKey.generate_version(),
            status='active'
        )
        
        url = '/api/keys_management/keys/list'
        params = self._get_params()
        params.update({
            'page': 1,
            'size': 10
        })
        
        response = self.client.get(url, params, **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 0)  # DetailResponse返回code=0
        self.assertIn('list', result['data'])
        self.assertIn('total', result['data'])
        self.assertGreaterEqual(result['data']['total'], 1)

    def test_get_root_key_detail(self):
        """测试获取根密钥详情"""
        # 先创建一个测试密钥
        root_key = RootKey.objects.create(
            key_id=RootKey.generate_key_id(),
            key=RootKey.generate_root_key(128),
            key_type='SM4',
            key_length=128,
            description='测试密钥',
            version=RootKey.generate_version(),
            status='active'
        )
        
        url = '/api/keys_management/keys/detail'
        params = self._get_params()
        params.update({
            'key_id': root_key.key_id
        })
        
        response = self.client.get(url, params, **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 0)  # DetailResponse返回code=0
        self.assertEqual(result['data']['key_id'], root_key.key_id)
        self.assertEqual(result['data']['key_type'], root_key.key_type)

    def test_get_root_key_detail_missing_key_id(self):
        """测试获取根密钥详情缺少key_id参数"""
        url = '/api/keys_management/keys/detail'
        params = self._get_params()
        
        response = self.client.get(url, params, **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('key_id参数不能为空', result['data'])

    def test_get_root_key_detail_not_found(self):
        """测试获取不存在的根密钥详情"""
        url = '/api/keys_management/keys/detail'
        params = self._get_params()
        params.update({
            'key_id': 'non_existent_key_id'
        })
        
        response = self.client.get(url, params, **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 400)  # ErrorResponse返回code=400
        self.assertIn('根密钥不存在', result['data'])

    def test_update_root_key_status(self):
        """测试更新根密钥状态"""
        # 先创建一个测试密钥
        root_key = RootKey.objects.create(
            key_id=RootKey.generate_key_id(),
            key=RootKey.generate_root_key(128),
            key_type='SM4',
            key_length=128,
            description='测试密钥',
            version=RootKey.generate_version(),
            status='active'
        )
        
        url = '/api/keys_management/keys/update'
        data = {
            'key_id': root_key.key_id,
            'status': 'inactive',
            'description': '更新后的描述'
        }
        # 添加签名参数到请求体
        data.update(self._get_params())
        
        response = self.client.put(url, data, format='json', **self._get_headers())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        
        result = response.json()
        self.assertEqual(result['code'], 0)  # DetailResponse返回code=0
        
        # 验证数据库中的状态已更新
        updated_key = RootKey.objects.get(key_id=root_key.key_id)
        self.assertEqual(updated_key.status, 'inactive')


class KeyAuditLogTest(TestCase):
    """密钥审计日志测试"""

    def test_create_audit_log(self):
        """测试创建审计日志"""
        audit_log = KeyAuditLog.objects.create(
            key_id='test_key_id',
            operation='create',
            operator='test_user',
            ip_address='127.0.0.1',
            user_agent='test_agent',
            details='测试审计日志',
            expired_at=datetime.now()
        )
        self.assertEqual(audit_log.key_id, 'test_key_id')
        self.assertEqual(audit_log.operation, 'create')
        self.assertEqual(audit_log.operator, 'test_user')
